package com.cloud.bssp.chinesenewyear.grabredenvelope.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.cloud.bssp.chinesenewyear.grabredenvelope.GlobalDataCache;
import com.cloud.bssp.chinesenewyear.grabredenvelope.GlobalInitProcessor;
import com.cloud.bssp.chinesenewyear.grabredenvelope.entity.GrabEnvelopeLogDO;
import com.cloud.bssp.chinesenewyear.grabredenvelope.entity.PeopleDO;
import com.cloud.bssp.chinesenewyear.grabredenvelope.entity.RedEnvelopeDO;
import com.cloud.bssp.chinesenewyear.grabredenvelope.service.IGrabRedEnvelopeService;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @description： 抢红包
 * @author：weirx
 * @date：2022/1/6 10:58
 * @version：3.0
 */
public class GrabRedEnvelopeServiceImpl implements IGrabRedEnvelopeService {
    @Override
    public void grab(Integer peopleId, Integer redEnvelopeId) throws Exception {
        // 获取全局变量
        GlobalDataCache globalDataCache = GlobalInitProcessor.getGlobalDataCache();
        // 获取用户
        Map<Integer, PeopleDO> peopleCache = globalDataCache.getPeopleCache();
        PeopleDO peopleDO = peopleCache.get(peopleId);
        // 获取红包
        Map<Integer, RedEnvelopeDO> redEnvelopeCache = globalDataCache.getRedEnvelopeCache();
        RedEnvelopeDO redEnvelopeDO = redEnvelopeCache.get(redEnvelopeId);
        // 获取红包历史
        Map<Integer, Map<Integer, GrabEnvelopeLogDO>> envelopeLogCache = globalDataCache.getEnvelopeLogCache();
        Map<Integer, GrabEnvelopeLogDO> integerGrabEnvelopeLogDOMap =
                envelopeLogCache.get(redEnvelopeDO.getId()) == null ? new HashMap<>(4)
                        : envelopeLogCache.get(redEnvelopeDO.getId());
        //判断红包是否还有余量
        if (redEnvelopeDO.getQuantity() > 0) {
            // 计算抢到的红包金额,并减去余额,和可抢数量
            BigDecimal sub = this.sub(redEnvelopeDO);
            // 用户增加余额
            peopleDO.setAmount(peopleDO.getAmount().add(sub));
            // 记录抢红包历史
            // 没有红包历史则新建，有则返回不能抢红包
            if (ObjectUtil.isNotEmpty(integerGrabEnvelopeLogDOMap) &&
                    ObjectUtil.isNotEmpty(integerGrabEnvelopeLogDOMap.get(peopleId))) {
                throw new Exception("很抱歉，您已抢过红包");
            } else {
                GrabEnvelopeLogDO grabEnvelopeLog = new GrabEnvelopeLogDO(peopleId, redEnvelopeId, sub, new Date());
                integerGrabEnvelopeLogDOMap.put(peopleId, grabEnvelopeLog);
                envelopeLogCache.put(redEnvelopeId, integerGrabEnvelopeLogDOMap);
                globalDataCache.setEnvelopeLogCache(envelopeLogCache);
            }
        } else {
            throw new Exception("很抱歉，红包已被抢完！");
        }
    }

    /**
     * description: 计算抢到的红包金额,并减去余额
     *
     * @param redEnvelopeDO
     * @return: BigDecimal
     * @author: weirx
     * @time: 2022/1/6 11:06
     */
    private BigDecimal sub(RedEnvelopeDO redEnvelopeDO) {
        BigDecimal scale;
        if (redEnvelopeDO.getQuantity() > 1) {
            // 计算能获取的最金额，指定最大最小范围
            int max = redEnvelopeDO.getAmount().intValue();
            double min = 0.01;
            // 随机范围，不会超过max，也不会小于min
            BigDecimal db = new BigDecimal(Math.random() * (max - min) + min);
            //保留两位小数，不四舍五入
            scale = db.setScale(2, BigDecimal.ROUND_DOWN);
        } else {
            // 剩一个则获取全部
            scale = redEnvelopeDO.getAmount();
        }
        //设置红包余额
        redEnvelopeDO.setAmount(redEnvelopeDO.getAmount().subtract(scale));
        //设置剩余可抢数量
        redEnvelopeDO.setQuantity(redEnvelopeDO.getQuantity() - 1);
        return scale;
    }
}
